/**
 * Copyright (c) 2010 BullionXpress.com,
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */

package com.bullionxpress.server.impl;

import com.bullionxpress.shared.service.DuplicateTickIDException;
import com.bullionxpress.shared.service.InvalidTickIDFormatException;
import com.bullionxpress.shared.service.TickNotFoundException;
import java.rmi.RemoteException;
import java.util.Date;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Vector;
import com.bullionxpress.shared.service.TickDatabase;
import com.bullionxpress.shared.model.Instrument;
import com.bullionxpress.shared.model.Tick;
import com.bullionxpress.shared.util.Log;
import java.sql.Timestamp;

public class TickManager extends java.rmi.server.UnicastRemoteObject implements TickDatabase {

    public TickManager() throws RemoteException {
        //What should go in the constructor?
        connect();
    }

    Connection conn = null;
    Statement statement = null;

    public void connect() {

        try {
            Log.info("Connecting to account");
            conn = DatabaseManager.getConnection();

            try {
                statement = conn.createStatement();
                statement.executeUpdate("CREATE TABLE IF NOT EXISTS history (id long, open float, high float, low float, close float, timestamp long, ts datetime, symbol varchar(16))"); // instrument id
            } catch (Exception ex) {
                ex.printStackTrace();
            }

        } catch (Exception ex) {
            ex.printStackTrace();
            System.exit(-1);
        }
    }

    /*
    public Tick[] getAll() {

        try {


            String query = "SELECT * FROM history";
            conn = DatabaseManager.getConnection();
            statement = conn.createStatement();
            ResultSet result = statement.executeQuery(query);

            Vector v = new Vector();
            while (result.next()) {
                Tick tick = get(result.getLong("id"));
                v.addElement(tick);
            }
            Log.info("Loaded: " + v.size() + " items");
            Tick[] tickList = new Tick[v.size()];
            for (int i = 0; i < v.size(); i++) {
                tickList[i] = (Tick) v.get(i);
            }
            return tickList;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

     */

    public Tick get(long id) throws TickNotFoundException {
        if (id == Tick.NOT_SPECIFIED) {
            throw new IllegalArgumentException();
        }
        String query = "SELECT * FROM history WHERE id = '" + id + "'";
        ResultSet result = null;
        boolean r = false;
        try {
            conn = DatabaseManager.getConnection();
            statement = conn.createStatement();
            result = statement.executeQuery(query);
            r = result.next();
        } catch (Exception ex) {
        }

        if (r) {
            Tick tick = new Tick();
            try {
                //tick.setOwner(result.getString("owner"));
                tick.setId(result.getLong("id"));
                tick.setInstrument(new Instrument(result.getString("symbol")));
                tick.setOpen(result.getDouble("open"));
                tick.setHigh(result.getDouble("high"));
                tick.setLow(result.getDouble("low"));
                tick.setClose(result.getDouble("close"));
                tick.setTimestamp(result.getLong("timestamp"));
            } catch(Exception ex){
                throw new TickNotFoundException();
            }
            return tick;
        } else {
            throw new TickNotFoundException();
        }
    }

    public void add(Tick b) throws DuplicateTickIDException, InvalidTickIDFormatException {

        if (b == null) {
            throw new IllegalArgumentException();
        } else if (b.getId() == Tick.NOT_SPECIFIED) {
            throw new InvalidTickIDFormatException();
        } 

        if( b.open < 0 || b.high < 0 || b.low < 0 || b.close < 0 ){
            throw new IllegalArgumentException("Tick has bad data");
        }
        
        try {
            Tick a = get(b.getId());
            throw new DuplicateTickIDException();
        } catch(TickNotFoundException ex){
            
        }

        String query = "INSERT INTO history (id, open, high, low, close, timestamp, ts, symbol)  VALUES (" + b.getId() + "," + b.getOpen() + "," + b.getHigh() + "," + b.getLow() + "," + b.getClose() + "," + b.getTimestamp() + ", '" + new Timestamp(b.getTimestamp()) + "', '" + b.getInstrument() + "')";
        int n = 0;
        try {
            conn = DatabaseManager.getConnection();
            statement = conn.createStatement();
            n = statement.executeUpdate(query);
        } catch (SQLException ex) {
            ex.printStackTrace();
            Log.info(ex);
        }
        if (n != 1) {
            throw new DuplicateTickIDException();
        }
    }

    public void delete(String id) throws TickNotFoundException, InvalidTickIDFormatException {

        if (id == null) {
            throw new IllegalArgumentException();
        } if( id.length() != 13 ){
            throw new InvalidTickIDFormatException();
        }

        String sql = "DELETE FROM history WHERE id = '" + id + "'";

        int n = 0;
        try {
            conn = DatabaseManager.getConnection();
            statement = conn.createStatement();
            n = statement.executeUpdate(sql);
            Log.info("DELETE:" + n);
        } catch (SQLException ex) {
            ex.printStackTrace();
        }

        if (n < 1) {
            throw new TickNotFoundException();
        }

    }

    @Deprecated
    public Tick[] getAllByInstrument(Instrument owner) throws TickNotFoundException {
        if (owner == null) {
            throw new IllegalArgumentException();
        }

        String query = "SELECT * FROM history WHERE symbol = '" + owner + "'";
        ResultSet result = null;
        try {
            conn = DatabaseManager.getConnection();
            statement = conn.createStatement();
            Log.info(query);
            result = statement.executeQuery(query);
        } catch (Exception ex) {
        }

        Vector v = new Vector();

        int c = 0;
        try {
            while (result.next()) {
                Tick tick = new Tick();
                tick = get(result.getLong("id"));
                v.addElement(tick);
                c++;
            }
        } catch (Exception ex) {
            throw new TickNotFoundException();
        }

        if (c == 0) {
            throw new TickNotFoundException();
        }

        Tick[] tickList = new Tick[v.size()];
        for (int i = 0; i < v.size(); i++) {
            tickList[i] = (Tick) v.get(i);
        }

        return tickList;

    }

    public void close() {
    }

    public int count() {
        int r = 0;

        return 0;
        //Tick[] b = getAll(); // must be replaced with count.
        //return b.length;
    }

    public Tick[] getAllAfterDateByInstrument(Instrument instrument, Date target) {
        try {
            if( target == null ){
                throw new IllegalArgumentException("Date target (from date) cannot be null");
            }
            if( instrument == null ){
                throw new IllegalArgumentException("Instrument cannot be null");
            }
            long time = target.getTime();
            String query = "SELECT * FROM history WHERE (ts BETWEEN '" + new Timestamp(time) + "' AND '" + new Timestamp(System.currentTimeMillis()) + "') AND symbol = '" + instrument.getSymbol() + "'";
            System.out.println(query);
            conn = DatabaseManager.getConnection();
            statement = conn.createStatement();
            ResultSet result = statement.executeQuery(query);
            //System.out.println(query);
            Vector v = new Vector();
            while (result.next()) {
                Tick tick = get(result.getLong("id"));
                v.addElement(tick);
            }
            Tick[] tickList = new Tick[v.size()];
            for (int i = 0; i < v.size(); i++) {
                tickList[i] = (Tick) v.get(i);
            }
            return tickList;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    

}
